using CfgTable;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GameAOT;
using System;
using UnityEngine;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    public class LevelPlayCameraCtrl : QuarterViewCameraController
    {
        public LevelPlayRegionController regionCtrl => parent as LevelPlayRegionController;
        public override Action<Func<UniTask>> AddPreloadAfterScene => regionCtrl.sceneCtrl.AddPreloadAfterScene;

        //timer
        private uint _moveTimerId;

        public LevelPlayCameraCtrl()
        {
            MsgDispatcher.AddListener<int>(MsgEventType.Level_NotifyStartCameraMotion, RecvStartCameraMotion);
        }

        protected override void OnSceneLoaded()
        {
            base.OnSceneLoaded();
            //注册手势事件处理函数（无需手动移除）
            regionCtrl.interactCtrl.AddTouchGestureEvent(CameraGesture);
            regionCtrl.interactCtrl.AddTouchUpEvent(CameraTouchUp);
            regionCtrl.interactCtrl.AddTouchTapEvent(CameraTouchTap);
        }

        protected override Transform GetPlayerEntityTransform()
        {
            return regionCtrl.entityCtrl.GetMainCharacter()?.transform;
        }

        protected override int GetSceneDefaultCameraCid()
        {
            return regionCtrl.cfgRegionPack.cfgScene.DefaultCamera;
        }

        protected override int GetSavedCameraCid()
        {
            return regionCtrl.levelPlayCtrl.levelPlayer.customCameraCid;
        }

        /// <summary>
        /// 播放镜头切换动画
        /// </summary>
        /// <param name="screenSwitchCfg"></param>
        /// <param name="active">是否开启新虚拟相机，否则重置</param>
        /// <returns></returns>
        private async UniTask PlayScreenSwitchInternal(CfgLevelScreenSwitch screenSwitchCfg, bool active)
        {
            regionCtrl.interactCtrl.Standby();
            var oldCameraState = cameraState;
            cameraState = CameraStateType.ScreenSwitch;
            switch (screenSwitchCfg.SwitchType)
            {
                case LevelCameraSwitchType.SmoothMove:
                    var oldTime = cinemachineBrain.m_DefaultBlend.m_Time;
                    cinemachineBrain.m_DefaultBlend.m_Time = screenSwitchCfg.MoveTime.MillisecToSec();
                    vc_MoveTarget.gameObject.SetActive(active);
                    _moveTimerId = TimerManager.Instance.StartOneTimer(screenSwitchCfg.MoveTime.MillisecToSec());
                    await _moveTimerId.AwaitTimer();
                    _moveTimerId = 0;
                    cinemachineBrain.m_DefaultBlend.m_Time = oldTime;
                    break;
                case LevelCameraSwitchType.DirectCut:
                    vc_MoveTarget.gameObject.SetActive(active);
                    cinemachineBrain.ExInstantManualUpdate();
                    break;
                default:
                    return;
            }

            // 等待时间
            if (screenSwitchCfg.Duration > 0)
            {
                _moveTimerId = TimerManager.Instance.StartOneTimer(screenSwitchCfg.Duration.MillisecToSec());
                await _moveTimerId.AwaitTimer();
                _moveTimerId = 0;
            }

            if (screenSwitchCfg.JumpId > 0)
            {
                var nextCfg = TableCenter.levelScreenSwitch.Get(screenSwitchCfg.JumpId);
                await PlayCameraScreenSwitch(nextCfg);
            }

            cameraState = oldCameraState;
            regionCtrl.interactCtrl.QuitStandby();
        }

        /// <summary>
        /// 播放镜头切换动画
        /// </summary>
        /// <param name="screenSwitchCfg"></param>
        /// <returns></returns>
        public async UniTask PlayCameraScreenSwitch(CfgLevelScreenSwitch screenSwitchCfg)
        {
            int tagOrMcid = screenSwitchCfg.TargetEntity;
            LevelPlayBaseEntity entity = null;
            if (tagOrMcid > 0)
            {
                bool useTag = LevelDataUtil.IsEntityTag(tagOrMcid);
                foreach (var kv in this.regionCtrl.entityCtrl.entitys)
                {
                    if ((useTag && kv.Value.ContainTag((ushort)tagOrMcid)) || (!useTag && kv.Value.GetDynLevelEntity().mcid == tagOrMcid))
                    {
                        entity = kv.Value;
                        break;
                    }
                }
                if (entity == null)
                {
                    LogGame.LogError($"根据tagId：{tagOrMcid} 找不到实体，请确保该实体在AOI范围内。");
                    return;
                }
                Vector3 pos = entity.GetUnityVec3Pos();
                targetMain.position = pos;
                await PlayScreenSwitchInternal(screenSwitchCfg, true);
            }
            else if (screenSwitchCfg.TargetPosition.Count == 3)
            {
                var pos = screenSwitchCfg.TargetPosition.ToVector3(GameGlobalConst.LogicPosScale);
                targetMain.position = pos;
                await PlayScreenSwitchInternal(screenSwitchCfg, true);
            }
            else if (tagOrMcid < 0)
            {
                await PlayScreenSwitchInternal(screenSwitchCfg, false);
            }
        }

        /// <summary>
        /// 接收开始镜头切换
        /// </summary>
        /// <param name="levelScreenSwitchCid"></param>
        public void RecvStartCameraMotion(int levelScreenSwitchCid)
        {
            var screenSwitchCfg = TableCenter.levelScreenSwitch.Get(levelScreenSwitchCid);
            if (screenSwitchCfg == null)
            {
                LogGame.LogError($"[{nameof(levelScreenSwitchCid)}|RecvStartCameraMotion]level screen switch cid is null:{levelScreenSwitchCid}");
                return;
            }
            PlayCameraScreenSwitch(screenSwitchCfg).Forget();
        }

        protected override void OnDispose()
        {
            base.OnDispose();
            MsgDispatcher.RemoveListener<int>(MsgEventType.Level_NotifyStartCameraMotion, RecvStartCameraMotion);

            if (_moveTimerId > 0)
            {
                _moveTimerId.StopTimer();
                _moveTimerId = 0;
            }
        }
    }
}
